﻿#region Summary

// 
// Owner : JackieHan 
// 
// Solution : Erp 
// 
// Project : Jackie.Utility
// 
// File : TypeExtension.cs
// 
// CopyRight : Copyright © 2010-2011 Skomart Corporation, All Rights Reserved 
// 
// Summary : Type 扩展
// 
// History : 
//			2012-07-13 17:39:02	    Create 
// 

#endregion

#region Using

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;

#endregion

namespace Jackie.Utility.CustomExtension
{
    ///<summary>
    ///Type 扩展
    ///</summary>
    public static class TypeExtension
    {
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="expression"></param>
        /// <returns></returns>
        public static IList<MemberInfo> DecodeMembersAccessExpression<TEntity>(Expression<Func<TEntity, object>> expression)
        {
            List<MemberInfo> members = new List<MemberInfo>();
            if (expression.Body.NodeType != ExpressionType.MemberAccess)
            {
                if ((expression.Body.NodeType == ExpressionType.Convert) && (expression.Body.Type == typeof(object)))
                {
                    var operandExpression = (MemberExpression)((UnaryExpression)expression.Body).Operand;
                    var childExpression = operandExpression.Expression as MemberExpression;
                    if (childExpression != null && childExpression.NodeType == ExpressionType.MemberAccess)
                    {
                        var member = childExpression.Member;
                        members.Add(member);
                    }

                    var childMember = operandExpression.Member;
                    members.Add(childMember);
                }
                else
                    throw new Exception(string.Format("Invalid expression type: Expected ExpressionType.MemberAccess, Found {0}",
                                                      expression.Body.NodeType));
            }
            else
            {
                var memberExpression = (MemberExpression) expression.Body;
                var childExpression = memberExpression.Expression as MemberExpression;
                if (childExpression != null && childExpression.NodeType == ExpressionType.MemberAccess)
                {
                    var member = childExpression.Member;
                    members.Add(member);
                }
                var childMember = memberExpression.Member;
                members.Add(childMember);
            }
            return members;
        }

        /// <summary>
        /// 解析属性访问表达式 返回MemberInfo
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="expression"></param>
        /// <returns></returns>
        public static MemberInfo DecodeMemberAccessExpression<TEntity>(Expression<Func<TEntity, object>> expression)
        {
            if (expression.Body.NodeType != ExpressionType.MemberAccess)
            {
                if ((expression.Body.NodeType == ExpressionType.Convert) && (expression.Body.Type == typeof(object)))
                {
                    return ((MemberExpression)((UnaryExpression)expression.Body).Operand).Member;
                }
                throw new Exception(string.Format("Invalid expression type: Expected ExpressionType.MemberAccess, Found {0}",
                                                  expression.Body.NodeType));
            }
            return ((MemberExpression)expression.Body).Member;
        }

        /// <summary>
        /// 解析属性访问表达式 返回MemberInfo
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="expression"></param>
        /// <returns></returns>
        public static MemberInfo DecodeMemberAccessExpression<TEntity, TProperty>(Expression<Func<TEntity, TProperty>> expression)
        {
            if (expression.Body.NodeType != ExpressionType.MemberAccess)
            {
                if ((expression.Body.NodeType == ExpressionType.Convert) && (expression.Body.Type == typeof(object)))
                {
                    return ((MemberExpression)((UnaryExpression)expression.Body).Operand).Member;
                }
                throw new Exception(string.Format("Invalid expression type: Expected ExpressionType.MemberAccess, Found {0}",
                                                  expression.Body.NodeType));
            }
            return ((MemberExpression)expression.Body).Member;
        }
    }
}